import React, {useCallback, useEffect, useMemo, useState} from "react";
import {useDropzone} from 'react-dropzone'
import Select from "react-select";
import '../../assets/scss/components/general/fileUpload.scss'
import {FilesService} from "../../services/files/files.service";
import ComponentSpinner from "../@vuexy/spinner/Full-loading-spinner";

export const FileUpload = props => {
  const {withoutAuth, userId, verifyId, invalid, type, file, fileUploaded} = props
  const [files, setFiles] = useState([])
  const [spinner, setSpinner] = useState(false)

  const getFiles = () => {
    if (!withoutAuth || verifyId)
      FilesService.index({type: type || null}).then(response => {
        let payload = response.data.files.data || []
        setFiles(payload);
      })
  }

  const createFile = (formData) => {
    FilesService.create(formData).then(response => {
      let payload = response.data.file || null
      if (payload)
        fileUploaded(payload)
    }).finally(() => {
      getFiles()
      setSpinner(false)
    })
  }

  const createWithoutAuthFile = (formData) => {
    formData.append('user_id', userId || null);
    FilesService.createWithoutAuth(formData).then(response => {
      let payload = response.data.file || null
      if (payload) {
        setFiles([payload]);
        fileUploaded(payload)
      }
    }).finally(() => {

      setSpinner(false)
    })
  }

  useEffect(() => {
    getFiles()
  }, [])

  const maxSize = 16777216;

  const onDrop = useCallback(acceptedFiles => {
    setSpinner(true)
    const formData = new FormData();
    formData.append('file', acceptedFiles[0]);
    formData.append('type', type || null);
    if (!withoutAuth || verifyId)
      createFile(formData)
    else
      createWithoutAuthFile(formData)
  }, []);

  const {isDragActive, isDragAccept, getRootProps, getInputProps, isDragReject, rejectedFiles} = useDropzone({
    onDrop,
    minSize: 0,
    maxSize,
    multiple: false
  });

  const isFileTooLarge = rejectedFiles.length > 0 && rejectedFiles[0].size > maxSize;

  const baseStyle = {
    display: 'flex',
    alignItems: 'center',
    justifyContent: 'center',
    flexWrap: 'wrap',
    paddingBottom: '1.5rem',
    borderWidth: '0.8px',
    borderRadius: '5px',
    borderColor: '#6F64F8',
    borderStyle: 'dashed',
    backgroundColor: 'rgba(81, 166, 145, 0.07)',
    color: '#6F64F8',
    outline: 'none',
    transition: 'border .24s ease-in-out',
    minHeight: '87px'
  };

  const activeStyle = {
    boxShadow: '0px 0px 5px rgba(111, 100, 248, 0.83)'
  };

  const acceptStyle = {
    borderColor: '#6F64F8',
  };

  const rejectStyle = {
    borderColor: '#ff1744',
    color: '#ff1744'
  };

  const selectStyles = {
    position: "absolute"
  }

  const style = useMemo(() => ({
    ...baseStyle,
    ...(isDragActive ? activeStyle : {}),
    ...(isDragAccept ? acceptStyle : {}),
    ...(isDragReject ? rejectStyle : {})
  }), [isDragActive, isDragReject]);

  const clickMouse = event => {
    event.stopPropagation()
  }

  return (
    <div className="fileUpload position-relative">
      {spinner && <ComponentSpinner/>}
      <div
        {...getRootProps({
          style
        })}>

          <span onClick={clickMouse}
                id={'fileUpload'} className="pt-2 px-1">
          <Select
            className={`fileUpload-select ${invalid ? 'invalid-select' : ''}`}
            classNamePrefix="dark_select"
            isSearchable={false}
            placeholder="Выберите файл"
            options={files.map(el => {
              return {...el, value: el.id, label: `${el.name}.${el.extension}`}
            })}
            onChange={fileUploaded}
            value={file && {value: file.id, label: file.name}}
          />
        </span>


        <input {...getInputProps()}/>

        <span className="pt-2 px-1 d-flex flex-wrap">
          <span className="mx-auto pr-2">или</span>
          <span className="text-primary">
            {!isDragActive && 'Перетащите файлы сюда!'}
            {isDragActive && !isDragReject && 'Отпустите файл здесь!'}
            {isDragReject && 'Тип файла не принят!'}
          </span>
          {isFileTooLarge && (
            <span className="text-danger">
            Файл слишком большой.
          </span>
          )}
        </span>
      </div>
    </div>
  )
}
